#!/usr/bin/env python

import imaplib, email
import dbf
import tempfile
import os
import shutil

# IMAP version 4 is described in RFC1730

class ImapDownloader:

    def __init__(self, username, password, host, port=993, use_ssl=True):
        if use_ssl == True:
            self.imap_server = imaplib.IMAP4_SSL(host, port)
        else:
            self.imap_server = imaplib.IMAP4(host, port)

        self.username   = username
        self.password   = password
        self.logged_in  = False
        self.some_files_could_not_be_read = False

    def check_for_new_messages(self):
        # this should be called periodically on an open connection
        # because it only works for updates since last check on an open connection.
        r = self.imap_server.recent()
        if r[0] == 'OK':
            print 'Verific daca exista email nou'
            if r[1] == [None]:
                print 'Nu exista email nou'
            else:
                print 'Printez lista emailurilor noi'
                print r[1]

    def login(self):
        print 'Ma autentific cu serverul'
        self.imap_server.login(self.username, self.password)
        print 'Cea mai recenta versiune de protocol suportata de server este ' + self.imap_server.PROTOCOL_VERSION
        self.logged_in = True

    def logout(self):
        print 'Ma deconectez de la server'
        self.imap_server.close()
        self.imap_server.logout()
        self.logged_in = False

    def get_dbf_attachments(self, save_to, temp_path=tempfile.gettempdir()):
        if not self.logged_in:
            return

        self.some_files_could_not_be_read = False

        print 'Selectez folderul INBOX in modul doar-citire'
        r = self.imap_server.select('INBOX', readonly=True)
        #r = self.imap_server.select('Archives.2012', readonly=True)
        #print self.imap_server.list()
        if r[0] == 'OK':
            print 'INBOX are ' + str(r[1][0]) + ' mesaje'
        else:
            raise Exception('Nu am putut selecta folderul')

        # Get a list of all emails in INBOX
        typ, data = self.imap_server.search(None, 'ALL')

        # Iterate over each message using its order number
        # (might change if a message is deleted or moved while iterating!)
        for num in data[0].split():
            typ, data = self.imap_server.fetch(num, '(RFC822)')  # recycle 'data' variable since it was only used once

            # Construct email object from string
            e = email.message_from_string(data[0][1])

            # Read attachments
            for part in e.walk():
                # If has attachment
                if (part.get('Content-Disposition')
                    and part.get('Content-Disposition').startswith("attachment")):

                    filename = part.get_filename()

                    if ((filename != None)
                        and (os.path.splitext(filename)[1].lower() == '.dbf')):

                        try:
                            # print 'Decoding ' + filename
                            buf = part.get_payload(decode=True) # decodes the content according to it's Content-Encoding into a str object

                            # print 'Writing file to temporary directory'
                            f = open(os.path.join(temp_path, filename), 'wb')
                            f.write(buf)
                            f.flush()

                            # Read file and determine how to name it and where to save it based on that
                            # print 'Reading file'
                            table = dbf.Table(os.path.abspath(f.name))
                            table.open()
                            record = table[0]

                            #workplace   = record['denumire']
                            #casa        = record['judet']
                            #data_start  = record['data_start']
                            #data_stop   = record['data_stop']

                            # use positional instead of keyword because I commented out
                            # an exception in dbf.py for duplicate field names
                            workplace = record[0].strip()
                            casa = record[1].strip()
                            data_start = record[31].strip()
                            data_stop = record[32].strip()

                            correct_path = save_to + '_'.join( (casa, data_start, data_stop, workplace) ) + '.dbf'
                            print 'SAVING ' + correct_path
                            shutil.copy(os.path.abspath(f.name), correct_path)
                        except:
                            print 'Exception while reading ' + filename
                            self.some_files_could_not_be_read = True
                        finally:
                            # print 'Removing temporary file'
                            table.close()
                            f.close()
                            os.remove(os.path.abspath(f.name))
                            # print ""


if __name__ == "__main__":
    print 'Programul ruleaza'
    downloader = ImapDownloader('sebastian@minifarm.ro', 'Sonnesfisea', 'isaccei.minifarm.ro')
    # downloader = ImapDownloader(raw_input('Username: '), raw_input('Password: '), 'isaccei.minifarm.ro')
    downloader.login()
    print 'Se descarca atasamentele... va rog asteptati...'
    downloader.get_dbf_attachments('/run/media/sebastian/Data64K/DBFConsmuri/', '/run/media/sebastian/Data64K/DBFConsmuri/temp_path/')  # always end in /
    downloader.logout()
    if downloader.some_files_could_not_be_read == True:
        print 'Anumite atasamente nu au putut fi citite si s-a sarit peste ele'
